home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Program: CShell
- ** File: file.c
- ** Some code from: Traffic Light 2.0 version, by Keith Rollin & John Harvey
- ** Modified by: Eric Soldan
- **
- ** Copyright © 1990-1991 Apple Computer, Inc.
- ** All rights reserved.
- */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "CShell.h" /* Get the CShell includes/typedefs, etc. */
- #include "CShellCommon.h" /* Get the stuff in common with rez. */
- #include "CShell.protos" /* Get the prototypes for CShell. */
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __UTILITIES__
- #include "Utilities.h"
- #endif
-
-
-
- /*****************************************************************************/
-
-
-
- static Boolean gIncNewFileNumFlag = true;
-
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
-
-
- /* This function disposes of the document. It checks to see if a file is
- ** currently open for the document. If it is, then the document is closed.
- ** Once there is no open file for the document, the memory occupied by the
- ** document is released.
- */
-
- #pragma segment File
- OSErr AppDisposeDocument(FileRecHndl frHndl)
- {
- OSErr err;
-
- err = noErr;
-
- if (frHndl) {
- if ((*frHndl)->fileState.fss.vRefNum != kInvalVRefNum)
- err = FSClose((*frHndl)->fileState.refNum);
- /* Close the file, if opened. */
-
- AppFreeDocument(frHndl);
- /* Free all application-specific ram for the document. */
-
- DisposHandle((Handle)frHndl);
- /* Release memory for the document handle. */
- }
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* This function returns whether or not the document is dirty.
- */
-
- #pragma segment File
- Boolean AppDocumentDirty(FileRecHndl frHndl)
- {
- return((*frHndl)->fileState.docDirty);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* This function creates a new document. A handle is created as the
- ** reference to the document. Header information is placed in this handle.
- ** The application-specific data follows this header information. The
- ** handle is returned (or nil upon failure), and typically the handle is
- ** then stored in the refCon field of the window. Note that this is a
- ** convention, and is not mandatory. This allows a document to exist that
- ** has no window. A document with no window is useful when the application
- ** is called from the finder in response to a print request. The document
- ** can be loaded and printed without involving a window on the screen.
- */
-
-
- #pragma segment File
- OSErr AppNewDocument(FileRecHndl *returnHndl)
- {
- static short untitledCount;
- FileRecHndl frHndl;
- FileRecPtr frPtr;
- Str255 untitled;
- char *pstr;
- OSErr err;
-
- err = memFullErr;
- if (*returnHndl = frHndl = (FileRecHndl)NewHandle(sizeof(FileRec))) {
- GetIndString(untitled, rMiscStrings, sOrigName);
- frPtr = *frHndl;
- frPtr->fileState.docDirty = false;
- frPtr->fileState.readOnly = false;
- frPtr->fileState.fss.vRefNum = kInvalVRefNum;
- frPtr->fileState.window = nil;
- pstr = (char *) &(frPtr->fileState.fss.name);
- pstrcpy(pstr, (char *) &untitled);
- if (gIncNewFileNumFlag) ++untitledCount;
- appendi2pstr(pstr, untitledCount);
- if (err = AppInitDocument(frHndl)) {
- DisposHandle((Handle)frHndl);
- *returnHndl = nil;
- }
- }
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- OSErr AppOpenDocument(FileRecHndl *result, FSSpecPtr fileToOpen,
- char permission)
- {
- StandardFileReply reply;
- short fileRefNum;
- FileRecHndl frHndl;
- OSErr err;
- FSSpec myFileSpec;
- DialogPtr openDialog;
- short item;
-
- *result = nil; /* Assume we will fail. */
-
- if (!fileToOpen) {
- if (DisplayGetFile(&reply)) /* Let the user decide which file. */
- myFileSpec = reply.sfFile; /* User's choice. */
- else
- return(userCanceledErr); /* User canceled. */
- }
- else
- myFileSpec = *fileToOpen; /* Pre-designated file to open. */
-
- if (err = AppNewDocument(&frHndl))
- return(err);
- /* We couldn't create an empty document, so give it up. */
-
- err = HOpen(myFileSpec.vRefNum, myFileSpec.parID,
- myFileSpec.name, permission, &fileRefNum);
-
- if (err == opWrErr) {
-
- ParamText(myFileSpec.name, nil, nil, nil);
- openDialog = GetCenteredDialog(rOpenReadOnly, nil, nil, (WindowPtr)-1L);
- if (!openDialog) {
- AppDisposeDocument(frHndl);
- return(err);
- }
-
- OutlineDialogItem(openDialog, kOpenYes);
- DoSetCursor(&QD(arrow));
- ModalDialog((ModalFilterProcPtr)keyEquivFilter, &item);
- DisposDialog(openDialog);
- if (item != kOpenYes) return(userCanceledErr);
-
- (*frHndl)->fileState.readOnly = true;
- err = HOpen(myFileSpec.vRefNum, myFileSpec.parID,
- myFileSpec.name, fsRdPerm, &fileRefNum);
- }
-
- if (err) {
- AppDisposeDocument(frHndl);
- return(err);
- }
-
- (*frHndl)->fileState.fss = myFileSpec;
- (*frHndl)->fileState.refNum = fileRefNum;
-
- if (err = AppReadDocument(frHndl)) {
- AppDisposeDocument(frHndl);
- return(err);
- }
-
- if ((*frHndl)->fileState.readOnly) {
- FSClose((*frHndl)->fileState.refNum);
- (*frHndl)->fileState.fss.vRefNum = kInvalVRefNum;
- } /* If it's read-only, we don't need the file left open. */
-
- *result = frHndl;
- return(noErr);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- OSErr AppSaveDocument(FileRecHndl frHndl, WindowPtr window, short saveMode)
- {
- Str255 closeOrQuit;
- short item;
- StandardFileReply reply;
- OSErr err;
- short fileRefNum;
- DialogPtr saveDialog;
- Boolean doPrompt;
-
- /* When entering, saveMode is set to the menu command number of the
- ** the item that prompted this. Current settings are iSave, iSaveAs,
- ** iClose, and iQuit.
- */
-
- if (saveMode != iSaveAs) { /* If regular save... */
- if (!AppDocumentDirty(frHndl)) /* If file clean... */
- return(noErr); /* Consider it saved. */
- }
-
- pstrcpy((char *) &reply.sfFile.name, (char *) &(*frHndl)->fileState.fss.name);
-
- if ((saveMode == iClose) || (saveMode == iQuit)) {
- /* If implicit save... */
-
- GetIndString(closeOrQuit, rMiscStrings,
- (saveMode == iClose) ? isClosing : sQuitting);
- ParamText(reply.sfFile.name, closeOrQuit, nil, nil);
-
- saveDialog = GetCenteredDialog(rYesNoCancel, nil, window, (WindowPtr)-1L);
-
- if (saveDialog) {
- OutlineDialogItem(saveDialog, kSaveYes);
- DoSetCursor(&QD(arrow));
- ModalDialog((ModalFilterProcPtr)keyEquivFilter, &item);
- DisposDialog(saveDialog);
- }
- else
- item = kSaveYes;
-
- if (item != kSaveYes) {
- err = noErr;
- if (item == kSaveCanceled) err = userCanceledErr;
- return(err);
- }
- }
-
- doPrompt = (
- (saveMode == iSaveAs) ||
- ((*frHndl)->fileState.fss.vRefNum == kInvalVRefNum)
- );
-
- if (doPrompt) {
- /* Prompt with SFGetFile if doing a Save As or have never saved before. */
-
- if (!DisplayPutFile(&reply))
- return(userCanceledErr);
- /* User canceled the save. */
-
- if ((*frHndl)->fileState.fss.vRefNum != kInvalVRefNum)
- FSClose((*frHndl)->fileState.refNum);
- /* Close the old file. Don't respond to any error here because
- ** the user may be trying to do a save-as because their old file
- ** is bad. If we fail to close the old file, and then respond
- ** to the error, the user won't get the opportunity to save
- ** their document to a new file.
- */
-
- if (err = Create_OpenFile(&reply.sfFile, &fileRefNum)) {
- (*frHndl)->fileState.fss.vRefNum = kInvalVRefNum;
- return(err);
- }
-
- (*frHndl)->fileState.fss = reply.sfFile;
- (*frHndl)->fileState.refNum = fileRefNum;
- /* This is the new file. */
-
- if (window) AppNewWindowTitle(window);
- }
-
- if (err = AppWriteDocument(frHndl))
- return(err);
-
- (*frHndl)->fileState.docDirty = false;
- (*frHndl)->fileState.readOnly = false;
- return(noErr);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* ConvertOldToNewSFReply
- **
- ** struct StandardFileReply { struct SFReply {
- ** Boolean sfGood; <- Boolean good;
- ** Boolean sfReplacing; <- Boolean copy;
- ** OSType sfType; <- OSType fType;
- ** FSSpec sfFile;
- ** vRefNum; <- real vRefnum from (short vRefNum)
- ** parID; <- real dirID from (short vRefNum)
- ** name; <- Str63 fName;
- ** ScriptCode sfScript; <- iuSystemScript
- ** short sfFlags; <- 0
- ** Boolean sfIsFolder; <- false
- ** Boolean sfIsVolume; <- false
- ** long sfReserved1; <- 0
- ** short sfReserved2; <- 0
- ** }; };
- */
-
- #pragma segment File
- void ConvertOldToNewSFReply(SFReply *oldReply, StandardFileReply *newReply)
- {
- OSErr err;
- long ignoredProcID;
-
- newReply->sfGood = oldReply->good;
- newReply->sfReplacing = oldReply->copy; /* Correct assignment? */
- newReply->sfType = oldReply->fType;
-
- err = GetWDInfo(oldReply->vRefNum,
- &newReply->sfFile.vRefNum,
- &newReply->sfFile.parID,
- &ignoredProcID);
- BlockMove((Ptr)&oldReply->fName,
- (Ptr)&newReply->sfFile.name,
- oldReply->fName[0]+1);
-
- /* Punt on the rest. */
- newReply->sfScript = iuSystemScript;
- newReply->sfFlags = 0;
- newReply->sfIsFolder = false;
- newReply->sfIsVolume = false;
- newReply->sfReserved1 = 0;
- newReply->sfReserved2 = 0;
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* Create_OpenFile
- **
- ** Opens the file specified by the passed FSSpec, creating it if it doesn't
- ** already exist. Refturns the refnum of the open file to the application.
- ** File Manager errors are reported and returned.
- */
-
- #pragma segment File
- OSErr Create_OpenFile(FSSpec *file, short *refNum)
- {
- OSErr err;
-
- err = HCreate(file->vRefNum, file->parID, file->name, docCreator, docFileType);
- if (err == dupFNErr) {
-
- /* The user already told Standard File to replace the old file
- so let's get rid of it. */
-
- HDelete(file->vRefNum, file->parID, file->name);
-
- /* Try creating it again. */
- err = HCreate(file->vRefNum, file->parID, file->name, docCreator, docFileType);
- }
-
- if (!err) {
- err = HOpen(file->vRefNum, file->parID, file->name, fsRdWrPerm, refNum);
- if (err)
- HDelete(file->vRefNum, file->parID, file->name);
- }
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* DisplayGetFile
- **
- ** Simple routine to display a list of files with our file type.
- */
-
- #pragma segment File
- Boolean DisplayGetFile(StandardFileReply *reply)
- {
- SFTypeList typeList = {docFileType};
- Point where = {100, 100};
- SFReply oldReply;
-
- if (gSystemVersion >= 0x0700) /* If new standard file available... */
- StandardGetFile(nil, 1, typeList, reply);
-
- else {
- SFGetFile(where, (ConstStr255Param) "\pSelect a document to open.",
- nil, 1, typeList, nil, &oldReply);
-
- ConvertOldToNewSFReply(&oldReply, reply);
- }
-
- return(reply->sfGood);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* DisplayPutFile
- **
- ** Displays the StandardFile PutFile dialog box. Fills out the passed reply
- ** record, and returns the sfGood field as a result.
- */
-
- #pragma segment File
- Boolean DisplayPutFile(StandardFileReply *reply)
- {
- Str255 prompt;
- Point where = {100, 100};
- SFReply oldReply;
-
- GetIndString(prompt, rMiscStrings, sSFprompt);
-
- if (gSystemVersion >= 0x0700) /* If new standard file available... */
- StandardPutFile(prompt, reply->sfFile.name, reply);
- else {
- SFPutFile(where, prompt, reply->sfFile.name, nil, &oldReply);
- ConvertOldToNewSFReply(&oldReply, reply);
- }
-
- return(reply->sfGood);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- void IncNewFileNum(Boolean flag)
- {
- gIncNewFileNumFlag = flag;
- }
-
-
-
-